package cn.imvc.app.models;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.puff.cache.redis.Redis;

import cn.imvc.app.domains.PageDomain;
import cn.imvc.app.entities.Goods;
import cn.imvc.app.entities.GoodsClass;
import cn.imvc.app.entities.IndexClass;
import cn.imvc.app.entities.IndexData;
import cn.imvc.app.entities.TypeValue;
import cn.imvc.app.repositories.GoodsRepository;
import cn.imvc.app.repositories.IndexClassRepository;
import cn.imvc.app.repositories.IndexDataRepository;
import cn.imvc.core.ICache;
import cn.imvc.util.ToolUtils;

@Service
public class IndexModelImpl implements IndexModel {
	@Autowired
	private IndexClassRepository indexClssRepository;
	@Autowired
	private IndexDataRepository indexDataRepository;
	@Autowired
	private GoodsRepository goodsRepository;
	@Autowired
	GoodsClassModel goodsClassModel;
	@Autowired
	TypeValueModel typeValueModel;
	@Autowired
	ICache cache;

	public Map<String, Object> getShowDate(Byte platForm) {
		Map<String, Object> result = null;
		PageDomain<GoodsClass> domain = null;
		String key = "indexClassList" + platForm;
		int minute = ToolUtils.getMinute(new Date());
		//cache.remove("DATA", key);
		while (true) {
			domain = cache.get("DATA", key);
			if (domain == null) {
				if (Redis.getInstance().setnx(key + minute, "aa") == 1) {
					result = new HashMap<>();
					Redis.getInstance().expire(key + minute, 20);
					List<IndexClass> classList = indexClssRepository.findByPlatformOrderBySortAsc(platForm);
					Map<String, List<IndexClass>> indexClassMap = classList.stream()
							.collect(Collectors.groupingBy(indexClass -> "indexClass" + indexClass.getShowType()));
					List<IndexData> indexDataList = indexDataRepository.findByIndexClassIn(classList);
					Map<String, List<IndexData>> indexDataMap = indexDataList.stream().collect(Collectors.groupingBy(indexData -> "dataListOfIndexClass"
							+ indexData.getIndexClass().getId() + (indexData.getPosition() == null || platForm != 2 ? "" : indexData.getPosition())));
					result.put("indexClasses", classList);
					// 排序
					if (indexDataMap != null) {
						for (Map.Entry<String, List<IndexData>> entry : indexDataMap.entrySet()) {
							entry.getValue().sort((a, b) -> {
								if (a.getSort() == null)
									return 1;
								if (b.getSort() == null)
									return -1;
								return a.getSort() - b.getSort();
							});
						}
					}
					result.put("indexDataMap", indexDataMap);
					result.put("indexClassMap", indexClassMap);
					if (platForm == (byte) 2) {// pc，显示商品信息
						List<IndexData> goodsIndexDataList = new ArrayList<IndexData>();
						List<IndexClass> carouselIndexClass = indexClassMap.get("indexClass203");
						List<IndexClass> cateGoryIndexClass = indexClassMap.get("indexClass204");
						int carouselIndexClassId = 0;
						int cateGoryIndexClassId = 0;
						if (carouselIndexClass != null && carouselIndexClass.size() > 0) {
							carouselIndexClassId = carouselIndexClass.get(0).getId();
						}
						//List<IndexData> cateGoryGoodsList = indexDataMap.get("dataListOfIndexClass" + cateGoryIndexClassId);
						List<IndexData> cateGoryGoodsList = new ArrayList<>();
						if (cateGoryIndexClass != null && cateGoryIndexClass.size() > 0) {
							for (IndexClass indexClass : cateGoryIndexClass) {
								int indexClassId = indexClass.getId();
								List<IndexData> cateGoryGoodsLeftList = indexDataMap.get("dataListOfIndexClass" + indexClassId+"1");
								List<IndexData> cateGoryGoodsCenterList = indexDataMap.get("dataListOfIndexClass" + indexClassId+"2");
								List<IndexData> cateGoryGoodsRightList = indexDataMap.get("dataListOfIndexClass" + indexClassId+"3");
								if(cateGoryGoodsLeftList!=null&&cateGoryGoodsLeftList.size()>0){
									cateGoryGoodsList.addAll(cateGoryGoodsLeftList);
								}
								if(cateGoryGoodsCenterList!=null&&cateGoryGoodsCenterList.size()>0){
									cateGoryGoodsList.addAll(cateGoryGoodsCenterList);
								}
								if(cateGoryGoodsRightList!=null&&cateGoryGoodsRightList.size()>0){
									cateGoryGoodsList.addAll(cateGoryGoodsRightList);
								}
							}
						}
						List<IndexData> carouselGoodsList = indexDataMap.get("dataListOfIndexClass" + carouselIndexClassId);
						if (carouselGoodsList != null && carouselGoodsList.size() > 0) {
							goodsIndexDataList.addAll(carouselGoodsList);
						}
						if (cateGoryGoodsList != null && cateGoryGoodsList.size() > 0) {
							goodsIndexDataList.addAll(cateGoryGoodsList);
						}
						if (goodsIndexDataList != null && goodsIndexDataList.size() > 0) {
							int[] goodsIds = goodsIndexDataList.stream().filter(indexData -> indexData.getDataId() != null)
									.mapToInt(indexData -> indexData.getDataId()).toArray();
							List<Goods> goodsList = goodsRepository.findByIdIn(goodsIds);
							if (goodsList != null && goodsList.size() > 0) {
								Map<String, List<Goods>> goodsMapWithIdKey = goodsList.stream()
										.collect(Collectors.groupingBy(goods -> "goodsId" + goods.getId()));
								result.put("goodsMapWithIdKey", goodsMapWithIdKey);
							}
						}
					}
					domain = new PageDomain<GoodsClass>();
					domain.setMapResult(result);
					cache.put("DATA", key, domain, 1800);
					Redis.getInstance().remove(key + minute);
					break;
				} else {
					try {
						Thread.sleep(2000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			} else {
				result = domain.getMapResult();
				break;
			}
		}
		// List<IndexClass> classList =
		// indexClssRepository.findByPlatformOrderBySortAsc(platForm);
		// result.put("indexClasses", classList);
		return result;
	}

	public List<IndexData> getDataListByShowTypeAndPlatform(Integer showType, byte platfrom) {
		List<IndexClass> indexClassList = indexClssRepository.findByPlatformAndShowTypeOrderBySortAsc(platfrom, showType);
		Integer indexClassId = 0;
		if (indexClassList != null && indexClassList.size() > 0) {
			indexClassId = indexClassList.get(0).getId();
		}
		return indexDataRepository.findByIndexClassId(indexClassId);
	}

	public Map<String, Object> getHeaderInfos(Map<String, Object> paramMap) {
		Integer typeClassId = (Integer) paramMap.get("typeClassId");
		Integer showType = (Integer) paramMap.get("showType");
		byte platform = (Byte) paramMap.get("platform");
		Map<String, Object> result = null;
		PageDomain<GoodsClass> domain = null;
		String key = "headerInfos" + platform;
		int minute = ToolUtils.getMinute(new Date());
		while (true) {
			domain = cache.get("DATA", key);
			if (domain == null) {
				if (Redis.getInstance().setnx(key + minute, "aa") == 1) {
					result = new HashMap<>();
					Redis.getInstance().expire(key + minute, 20);
					String formatedDate = ToolUtils.getFormatedCNdateWithWeek();
					Map<String, Object> classesMap = goodsClassModel.findAllWithGroup();
					List<TypeValue> typeValues = typeValueModel.findShowTypeValues(typeClassId, (byte) 1);
					result.put("formatedDate", formatedDate);
					result.putAll(classesMap);
					result.put("typeValues", typeValues);
					List<IndexData> popularizeDatas = getDataListByShowTypeAndPlatform(showType, platform);
					result.put("popularizeDatas", popularizeDatas);
					domain = new PageDomain<GoodsClass>();
					domain.setMapResult(result);
					cache.put("DATA", key, domain, 1800);
					Redis.getInstance().remove(key + minute);
					break;
				} else {
					try {
						Thread.sleep(2000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			} else {
				result = domain.getMapResult();
				break;
			}
		}
		return result;
	}

}
